using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

using System.Diagnostics;

namespace Camalon.ColorPicker 
{

	internal sealed class ColorRenderingValue 
	{

        private static bool _valueChanging;

		private static CMYK				_cmyk = ColorConverter.RGBtoCMYK( ColorRenderingValue.RGB);
		private static CmykColorRange	_cmykColorRange = CmykColorRange.Magenda;
		public static event EventHandler CmykColorRangeChanged;

		private static ColorRange _colorRange = ColorRange.Hue;

		private static int	_opacity = 255;

		private static int	_red;
		private static int	_green;
		private static int	_blue;

		private static int	_hue;
		private static int	_saturation;
		private static int	_brightness;

		public static event EventHandler ColorRangeChanged;
		public static event EventHandler ValueChanged;
		public static event EventHandler OpacityChanged	;

		
		private ColorRenderingValue() {}

		public static Color ARGBColor
		{
			get
			{
				if( ColorRenderingValue.ColorRange == ColorRange.None) return Color.Empty;
				
				Color color;
				if( ColorRenderingValue.ColorRange == ColorRange.Red || 
					ColorRenderingValue.ColorRange == ColorRange.Green||
					ColorRenderingValue.ColorRange == ColorRange.Blue)
					color =  ColorConverter.RgbToColor( ColorRenderingValue.RGB );
				else
					color = ColorConverter.HsbToColor( ColorRenderingValue.HSB );

				return Color.FromArgb( _opacity, color);
			}

		}


		public static Color Color
		{
			get
			{

				if( ColorRenderingValue.ColorRange == ColorRange.None) return Color.Empty;

				if( ColorRenderingValue.ColorRange == ColorRange.Red || 
					ColorRenderingValue.ColorRange == ColorRange.Green||
					ColorRenderingValue.ColorRange == ColorRange.Blue)
				{
					//return Color.FromArgb( _opacity, _red, _green, _blue);
					return ColorConverter.RgbToColor( ColorRenderingValue.RGB );
				}
				else
				{
					return ColorConverter.HsbToColor( ColorRenderingValue.HSB );
//					Color color = ColorConverter.HsbToColor( ColorRenderingValue.HSB );
//					return Color.FromArgb( _opacity, color);

				}

			}

			set
			{
				if( ColorRenderingValue.ColorRange == ColorRange.Red || 
					ColorRenderingValue.ColorRange == ColorRange.Green||
					ColorRenderingValue.ColorRange == ColorRange.Blue)
					ColorRenderingValue.RGB =  ColorConverter.ColorToRgb( value );
				else
					ColorRenderingValue.HSB =  ColorConverter.ColorToHsb( value );

				//_opacity = value.A;

			}
		}


		

		private static void RGBToHSB()
		{
			RGB rgb = ColorRenderingValue.RGB;

			HSB hsb = ColorConverter.RgbToHsb( rgb );
			_hue		= hsb.Hue;
			_saturation = hsb.Saturation;
			_brightness = hsb.Brightness;

			_cmyk = ColorConverter.RGBtoCMYK( rgb );

		}


		private static void HSBToRGB()
		{
			RGB rgb = ColorConverter.HsbToRgb( ColorRenderingValue.HSB );
			_red	= rgb.Red;
			_green	= rgb.Green;
			_blue	= rgb.Blue;

			_cmyk = ColorConverter.RGBtoCMYK( rgb );

		}


		public static RGB RGB
		{
			get{ return new RGB(_red, _green,_blue);}
			set
			{ 
				if( _valueChanging ) return;
				if( value.IsEqual( ColorRenderingValue.RGB)) return;

				_valueChanging = true;

				_red	= value.Red;
				_green	= value.Green;
				_blue	= value.Blue;


				RGBToHSB();

				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());
				_valueChanging = false;
			}
		}


		public static HSB HSB
		{
			get{ return new HSB( _hue, _saturation, _brightness);}
			set
			{ 
				if( _valueChanging ) return;
				if( value.IsEqual( ColorRenderingValue.HSB)) return;
				
				_valueChanging = true;

				_hue		= value.Hue;
				_saturation = value.Saturation;
				_brightness = value.Brightness;

				HSBToRGB();

				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());

				_valueChanging = false;
			}
		}


		public static ColorRange ColorRange
		{
			get { return _colorRange; }
			set 
			{ 
				if( value == _colorRange) return;
				_colorRange = value; 
				if( ColorRangeChanged != null) ColorRangeChanged( new ColorRenderingValue(),new EventArgs());
			}
		}


		public static CMYK CMYK
		{
			get{ return _cmyk;}
			set
			{ 
				if( _valueChanging ) return;


				if( value.IsEqual( _cmyk )) return;

				_valueChanging = true;

				_cmyk = value;
				
				RGB rgb = ColorConverter.CMYKtoRGB( _cmyk );
				_red	= rgb.Red;
				_green	= rgb.Green;
				_blue	= rgb.Blue;

				HSB hsb = ColorConverter.RgbToHsb( rgb);
				_hue		= hsb.Hue;
				_saturation = hsb.Saturation;
				_brightness = hsb.Brightness;

				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());

				_valueChanging = false;

			}
		}


		public static CmykColorRange CmykColorRange
		{
			get { return _cmykColorRange; }
			set 
			{ 
				if( value == _cmykColorRange) return;
				_cmykColorRange = value; 
				if( CmykColorRangeChanged != null) CmykColorRangeChanged( new ColorRenderingValue(),new EventArgs());
			}
		}


		/// <summary>
		/// Gets or sets the red coordinate.
		/// </summary>
		public static int Opacity
		{
			get { return _opacity; }
			set 
			{
				if( _opacity == value ) return;
				if( value > 255 ) value = 255;
				//if( value < MinimumOpacity ) value = MinimumOpacity;
				_opacity = value; 
				if( OpacityChanged != null) OpacityChanged( new ColorRenderingValue(), new EventArgs());
			}
		}



		/// <summary>
		/// Gets or sets the red coordinate.
		/// </summary>
		public static int Red 
		{
			get { return _red; }
			set 
			{
				if( _red == value ) return;
				if( value > 255 ) value = 255;
				if( value < 0 ) value = 0;
				_red = value; 
				RGBToHSB();
				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());
			}
		}

		/// <summary>
		/// Gets or sets the green coordinate.
		/// </summary>
		public static int Green 
		{
			get { return _green; }
			set 
			{ 
				if( _green == value ) return;
				if( value > 255 ) value = 255;
				if( value < 0 ) value = 0;
				_green = value; 
				RGBToHSB();
				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());
			}
		}

		/// <summary>
		/// Gets or sets the blue coordinate.
		/// </summary>
		public static int Blue 
		{
			get { return _blue; }
			set 
			{ 
				if( _blue == value ) return;
				if( value > 255 ) value = 255;
				if( value < 0 ) value = 0;
				_blue = value; 
				RGBToHSB();
				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());

			}
		}


		/// <summary>
		/// Gets or sets the hue coordinate.
		/// </summary>
		public static int Hue 
		{
			get { return _hue; }
			set 
			{ 
				if( _hue == value ) return;
				if( value > 360 ) value = 360;
				if( value < 0 ) value = 0;
				_hue = value; 
				HSBToRGB();
				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());

			}
		}

		/// <summary>
		/// Gets or sets the saturation coordinate.
		/// </summary>
		public static int Saturation 
		{
			get { return _saturation; }
			set 
			{ 
				if( _saturation == value ) return;
				if( value > 100 ) value = 100;
				if( value < 0 ) value = 0;

				_saturation = value;
				HSBToRGB();
				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());
			}
		}

		/// <summary>
		/// Gets or sets the brightness coordinate.
		/// </summary>
		public static int Brightness 
		{
			get { return _brightness; }
			set 
			{ 
				if( _brightness == value ) return;
				if( value > 100 ) value = 100;
				if( value < 0 ) value = 0;
				_brightness = value; 
				HSBToRGB();
				if( ValueChanged != null) ValueChanged( new ColorRenderingValue(), new EventArgs());
			}
		}


	}
}